package com.studyroom.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.studyroom.dto.Result;
import com.studyroom.dto.RoomMemberDTO;
import com.studyroom.entity.RoomMember;
import com.studyroom.dto.UserDTO;
import com.studyroom.mapper.RoomMemberMapper;
import com.studyroom.service.RoomMemberService;
import com.studyroom.utils.UserHolder;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;

import java.time.LocalDateTime;
import java.util.LinkedList;
import java.util.List;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;

import static com.studyroom.utils.DefaultContants.*;
import static com.studyroom.utils.RedisContants.*;

@Service
public class RoomMemberServiceImpl extends ServiceImpl<RoomMemberMapper,RoomMember> implements RoomMemberService {
    @Resource
    private StringRedisTemplate stringRedisTemplate;

    //线程池
    private static final ExecutorService CACHE_REBULD_EXECUTOR= Executors.newFixedThreadPool (10);
    @Override
    public Result join(RoomMemberDTO roomMember) {
        RoomMember member=query ().eq ("room_id",roomMember.getRoomId ()).eq ("seatnumber",roomMember.getSeatnumber ()).one ();
        if(member!=null){
            //该位置已被使用,返回错误信息
            return Result.fail ("该位置已被人占用");
        }
        //未被占用
        UserDTO me= UserHolder.getUser ();
        //查询当前用户的在线情况
        String onlineKey=ONLINE_KEY+me.getId ();
        Long count=stringRedisTemplate.getExpire (onlineKey);
        if(count>0){
            //在线中
            return Result.fail ("你已经在自习中了");
        }
        //不在线,将用户在线信息写入redis
        LocalDateTime time=LocalDateTime.now ();
        stringRedisTemplate.opsForValue ().set (onlineKey,time.toString ());
        stringRedisTemplate.expire (onlineKey,ONLINE_TTL,TimeUnit.SECONDS);
        //设置member信息
        roomMember.setUserId (me.getId ());
        roomMember.setCreated (time);
        //插入到数据库
        RoomMember saveMember=BeanUtil.copyProperties (roomMember,RoomMember.class);
        save (saveMember);
        return Result.ok ();
    }
    @Override
    public Result getByRoomId(Long roomId) {
        //从数据库查询
        List<RoomMemberDTO> roomMembers=getBaseMapper ().getByRoomId (roomId);

        List<RoomMemberDTO> list=new LinkedList<> ();

        //创建16个空闲自习室位置,并赋予座位号
        for(int i=1;i<=16;i++){
            RoomMemberDTO roomMember=new RoomMemberDTO ();
            roomMember.setSeatnumber (i);
            list.add (roomMember);
        }
        //将获取的成员信息替换对应的座位号
        for(RoomMemberDTO roomMember:roomMembers){
            String onlineKey=ONLINE_KEY+roomMember.getUserId ();
            //查询当前用户是否在线
            Long count=stringRedisTemplate.getExpire (onlineKey);
            if(count<0){
                //不在线,从数据库删除该用户信息
                removeById (roomMember.getId ());
            }else {
                //在线,获取成员上线时间
                String time=stringRedisTemplate.opsForValue ().get (onlineKey);
                roomMember.setCreated (LocalDateTime.parse (time));
                list.set (roomMember.getSeatnumber () - 1, roomMember);
            }
        }
        return Result.ok (list);
    }

    @Override
    public Result offline() {
        UserDTO me=UserHolder.getUser ();
        //删除数据库信息
        QueryWrapper wrapper=new QueryWrapper ();
        wrapper.eq ("user_id",me.getId ());
        boolean b=remove (wrapper);
        if(!b){
            return Result.fail ("该用户不在线");
        }
        //删除redis中的用户在线信息
        String onlineKey=ONLINE_KEY+me.getId ();
        stringRedisTemplate.delete (onlineKey);
        return Result.ok ();
    }

    @Override
    public Result refresh() {
        UserDTO me=UserHolder.getUser ();
        String onlineKey=ONLINE_KEY+me.getId ();
        Long count=stringRedisTemplate.getExpire (onlineKey);
        if(count<0){
            return Result.fail ("当前用户不在自习");
        }
        stringRedisTemplate.expire (onlineKey,ONLINE_TTL,TimeUnit.SECONDS);
        return Result.ok ();
    }

}
